<template>
  <div
    class="h-[10%] bg-gray-200 border-b border-gray-300 flex items-center px-3 justify-between"
  >
    <h3 class="font-semibold text-gray-900">{{ conversation?.title }}</h3>
    <span class="text-sm text-gray-500">{{
      dayjs(conversation?.updatedAt).format("YYYY-MM-DD")
    }}</span>
  </div>
  <div class="w-[80%] mx-auto h-[75%] overflow-y-auto pt-2">
    <MessageList
      :messages="filteredMessages"
      ref="messageListRef"
    ></MessageList>
  </div>
  <div class="w-[80%] mx-auto h-[15%] flex items-center">
    <MessageInput
      v-model="inputValue"
      @create="sendNewMessage"
      :disabled="messageStore.isMessageLoading"
    />
  </div>
</template>
<script lang="ts" setup>
import { ref, watch, onMounted, computed, nextTick } from "vue";
import { useRoute } from "vue-router";
import dayjs from "dayjs";
import { cloneDeep } from "lodash";
import { useConversationStore } from "../stores/conversation";
import { useMessageStore } from "../stores/message";
import { useProviderStore } from "../stores/provider";
import MessageInput from "../components/MessageInput.vue";
import MessageList from "../components/MessageList.vue";
import {
  ConversationProps,
  MessageProps,
  MessageStatus,
  MessageListInstance
} from "../types";

const route = useRoute();
const conversationStore = useConversationStore();
const messageStore = useMessageStore();
const provdierStore = useProviderStore();

const conversationId = ref(parseInt(route.params.id as string));
const initMessageId = parseInt(route.query.init as string);
const inputValue = ref("");
let currentMessageListHeight = 0;
const messageListRef = ref<MessageListInstance>();
const filteredMessages = computed(() => messageStore.items);
const conversation = computed(() =>
  conversationStore.getConversationById(conversationId.value)
);
const lastQuestion = computed(() =>
  messageStore.getLastQuestion(conversationId.value)
);
const sendedMessages = computed(() =>
  filteredMessages.value
    .filter(
      (message: any) =>
        message.status !== "loading" && message.status !== "error"
    )
    .map((message: any) => {
      return {
        role: message.type === "question" ? "user" : "assistant",
        content: message.content,
        ...(message.imagePath && { imagePath: message.imagePath })
      };
    })
);
const sendNewMessage = async (question: string, imagePath?: string) => {
  if (question) {
    let copiedImagePath: string | undefined;
    if (imagePath) {
      try {
        copiedImagePath = await window.chatAPI.copyImageToUserDir(imagePath);
      } catch (error) {
        console.error("Failed to copy image:", error);
      }
    }
    const date = new Date().toISOString();
    await messageStore.createMessage({
      content: question,
      conversationId: conversationId.value,
      createdAt: date,
      updatedAt: date,
      type: "question",
      ...(copiedImagePath && { imagePath: copiedImagePath })
    });
    inputValue.value = "";
    creatingInitialMessage();
  }
};

const messageScrollToBottom = async () => {
  await nextTick();
  if (messageListRef.value) {
    messageListRef.value.ref.scrollIntoView({
      block: "end",
      behavior: "smooth"
    });
  }
};

const creatingInitialMessage = async () => {
  const createdData: Omit<MessageProps, "id"> = {
    content: "",
    conversationId: conversationId.value,
    type: "answer",
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    status: "loading"
  };
  const newMessageId = await messageStore.createMessage(createdData);
  await messageScrollToBottom();

  if (conversation.value) {
    const provider = provdierStore.getProviderById(
      conversation.value.providerId
    );

    if (provider) {
      window.chatAPI.startChat({
        messageId: newMessageId,
        providerName: provider.name,
        selectedModel: conversation.value.selectedModel,
        messages: sendedMessages.value
      });
    }
  }
};

watch(
  () => route.params.id,
  async (newId: string) => {
    conversationId.value = parseInt(newId);
    await messageStore.fetchMessagesByConversation(conversationId.value);
    await messageScrollToBottom();
    currentMessageListHeight = 0;
  }
);

const checkAndScrollToBottom = async () => {
  if (messageListRef.value) {
    const newHeight = messageListRef.value.ref.clientHeight;
    if (newHeight > currentMessageListHeight) {
      currentMessageListHeight = newHeight;
      await messageScrollToBottom();
    }
  }
};

onMounted(async () => {
  await messageStore.fetchMessagesByConversation(conversationId.value);
  await messageScrollToBottom();

  if (initMessageId) {
    await creatingInitialMessage();
  }
  let streamContent = "";

  window.chatAPI.onUpdateMessage(async (streamData: any) => {
    // console.log("streamData--", streamData);
    const { messageId, data } = streamData;
    streamContent += data.result;
    const getMessageStatus = (data: any): MessageStatus => {
      if (data.is_error) {
        return "error";
      } else if (data.is_end) {
        return "finished";
      } else {
        return "streaming";
      }
    };

    const updatedData = {
      content: streamContent,
      status: getMessageStatus(data),
      updatedAt: new Date().toISOString()
    };
    await messageStore.updateMessage(messageId, updatedData);
    await nextTick();
    await checkAndScrollToBottom();
    if (data.is_end) {
      streamContent = "";
    }
  });
});
</script>
